#ifndef GMPINT_H
#define GMPINT_H

#include <gmp.h>
#include <gmpxx.h>
#include <stdexcept>

class GMPInt {
private:
    mpz_t value;

public:
    // 构造函数与析构函数
    GMPInt();
    explicit GMPInt(int src);
    explicit GMPInt(const mpz_t src);
    
    GMPInt(const GMPInt& other);
    GMPInt(GMPInt&& other) noexcept;
    ~GMPInt();

    // 赋值运算符
    GMPInt& operator=(const GMPInt& other);
    GMPInt& operator=(GMPInt&& other) noexcept;
    GMPInt& operator=(mpz_t& other) noexcept;
    GMPInt& operator=(mpz_t&& other) noexcept;
    GMPInt& operator=(const int other) noexcept;
    // 算术运算符
    GMPInt operator+(const GMPInt& other) const;
    GMPInt operator+(const int& other) const;
    GMPInt operator-(const GMPInt& other) const;
    GMPInt operator-() const;
    GMPInt operator-(int other) const;
    GMPInt operator*(const GMPInt& other) const;
    GMPInt operator*(const int& other) const;
    GMPInt operator/(const GMPInt& other) const;
    GMPInt operator/(const int& other) const;
    GMPInt operator%(const GMPInt& other) const;
    GMPInt operator%(const int& other) const;

    // 复合赋值运算符
    GMPInt& operator/=(const int& other);
    GMPInt& operator%=(const int& other);

    // 比较运算符
    bool operator==(const GMPInt& other) const;
    bool operator==(const int& other) const;
    bool operator<(const GMPInt& other) const;
    bool operator<(const int& other) const;
    bool operator>(const GMPInt& other) const;
    bool operator>(const int& other) const;
    bool operator<=(const int& other) const;
    bool operator>=(const GMPInt& other) const;

    // 友元运算符
    friend GMPInt operator-(int value, const GMPInt& p);
    friend GMPInt operator*(int value, const GMPInt& p);

    // 类型转换运算符
    operator const mpz_t&() const;
    operator mpz_t&();

    GMPInt powm(const GMPInt& exp, const GMPInt& mod);
    std::string to_str() const;
    int set_by_str(const std::string& str);

};

// 非成员比较运算符声明
bool operator!=(const GMPInt& lhs, const GMPInt& rhs);
// 类似添加其他非成员比较运算符...

#endif // GMPINT_H